Примитивный запрос — простой джойн и группировка. Традиционные методы оптимизации — казалось бы, что могло пойти не так?..
Небольшой эксперимент, на тему необходимости проверки любых гипотез в конкретных условиях.
Возьмем исходный запрос:
WITH vals AS ( SELECT i , unnest('{1,2,3,4,5,6,7,8}'::integer[]) v FROM generate_series(1, 10000) i ) SELECT v2.i , sum(v1.v) FROM vals v1 JOIN vals v2 USING(i) GROUP BY 1;
294ms — это будет наше стартовое время, которое мы попробуем ускорить. Ну и 640K записей, которые пришлось обработать в Merge Join
.
Внимание на ключи группировки!
У нас в запросе используется USING(i)
— то есть ON v1.i = v2.i
, а потом — GROUP BY 1
— группировка по первому полю результата, которым в нашем случае является v2.i
.
То есть происходит группировка по полю связанной таблицы, а сама агрегация — по данным основной таблицы! Не надо так. Этим вы отсекаете планировщику возможность рассмотреть вариант соединения таблиц уже после группировки.
Исправим